package com.csii.mobilebanking.tool;

import java.io.IOException;
import java.lang.reflect.Field;
import java.net.URLDecoder;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.List;
import org.apache.http.HttpEntity;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.util.EntityUtils;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import android.text.format.Time;

public class JsonUtils {
	
	

	private static final String libperfix="ycb.lottery.json.utils.";

	public static Time NewGMTTime ()
	{
		Time time=new Time("GMT+8");
		long offset=1000*60*60*8;
		time.set( System.currentTimeMillis()+offset);
		return time;
	}

	private static String FixJsonBug(String string)
	{		
		if (string == null || string.length() == 0) {
			return "";
		}

		int i;
		int len = string.length();
		char c = 0;
		String hhhh;
		StringBuilder sb = new StringBuilder(len + 4);

		for (i = 0; i < len; i += 1) {
			c = string.charAt(i);
			if (c < ' ' || c >= '\u0080' ) {
				hhhh = "000" + Integer.toHexString(c);
				sb.append("/u" + hhhh.substring(hhhh.length() - 4).toUpperCase());
			} else {
				sb.append(c);
			}
		}	        	        
		return sb.toString();	    
	}

	private static String toHexString(byte[] bytes, String separator) 
	{
		StringBuilder hexString = new StringBuilder();
		for (byte b : bytes) {
			hexString.append(Integer.toHexString(b) ).append(separator);
		}
		return hexString.toString();
	}

	private static String toMd5(byte[] bytes) 
	{
		try 
		{
			MessageDigest algorithm = MessageDigest.getInstance("MD5");
			algorithm.reset();
			algorithm.update(bytes);
			return toHexString(algorithm.digest(), "-");
		} 
		catch (NoSuchAlgorithmException e) 
		{
			e.printStackTrace();
			//			Log.e(csTAG, e.toString());
			return "";
		}
	}

	public static String MD5Hash(String inputString)
	{
		byte[] buf=inputString.getBytes();
		return toMd5(buf);
	}

	//Time To String
	private static String ConvertTime(Time time)
	{    	
		return time.format("%Y-%m-%dT%H:%M:%S");
	}



	//String To JsonObject
	public static JSONObject cxmGetJsonObject(String json) throws JSONException{
		if (json == null || json.trim().length() == 0)
			return null;
		return new JSONObject(json);
	}

	// BaseType To Json String not with VarName
	private static String cxmGetRoJsonStr(Object obj) throws IllegalArgumentException, IllegalAccessException, JSONException {
		JSONObject jo = new JSONObject();
		Field[] selfFields = obj.getClass().getDeclaredFields();
		Field[] superfields = obj.getClass().getSuperclass().getDeclaredFields();
		// System.arraycopy(src, srcPos, dst, dstPos, length)
		Field[] fullFields = new Field[selfFields.length + superfields.length];
		System.arraycopy(selfFields, 0, fullFields, 0, selfFields.length);
		System.arraycopy(superfields, 0, fullFields, selfFields.length, superfields.length);
		String fname ;
		String tname ;
		Class<?> fieldtype;
		for (int i = 0; i < fullFields.length; i++) {
			Field afield = fullFields[i];
			afield.setAccessible(true);	    
			fname = afield.getName();
			tname = afield.getType().getName();
			fieldtype=afield.getType();
			fullFields[i].setAccessible(true);
			if (afield.get(obj) != null) {
				// Log.i("wh", fields[i].getType().getName());
				if (tname.indexOf(libperfix) > -1) {
					JSONObject jolv1 = new JSONObject(cxmGetRoJsonStr(afield.get(obj)));
					jo.put(fname, jolv1);
				} else if (fieldtype==String.class||fieldtype==CharSequence.class) {
					jo.put(fname, FixJsonBug((String) afield.get(obj)));
				} else if (fieldtype==Time.class) {
					jo.put(fname, ConvertTime((Time) afield.get(obj)));
				} else {
					jo.put(fname, afield.get(obj).toString());
				}
			}
		}
		return jo.toString().replaceAll("/u", "\\u");
	}



	public static <T> String cxmGetRoJsonStr(List<T> objList) throws IllegalArgumentException, IllegalAccessException, JSONException{
		Object[] objs = objList.toArray();
		int length = objs.length;
		int length2 = length - 1;
		if (length == 0)
		{
			return "[]";
		}
		else 
		{
			String mS = cxm_SimpleTypeArray_JsonStr(objs);
			if (mS.equals(""))
			{
				if (length == 1)
				{
					return "[" + cxmGetRoJsonStr(objs[0])  + "]";
				}
				else 
				{
					String tmpStr = "";
					for(int i = 0; i < length2; i++){
						tmpStr = tmpStr + cxmGetRoJsonStr(objs[i]) + ',';
					}
					return "[" + tmpStr + cxmGetRoJsonStr(objs[length2])  + "]";
				}
			}
			else
			{
				return mS;
			}
		}
	}

	//JSONObject to JSONObject
	public static JSONObject cxmGetJsonObject(JSONObject result, String object_name) throws JSONException{
		if (result.has(object_name)&&(!result.isNull(object_name))){
			return result.getJSONObject(object_name);	
		}else{
			return null;
		}
	}

	public static JSONArray cxmGetJsonArray(JSONObject result, String array_name) throws JSONException {
		if (result.has(array_name)&&(!result.isNull(array_name))){
			return result.getJSONArray(array_name);
		}else{
			return null;
		}
	}

	//send message and return message
	public static String cxm_http_request(String json, String URL) throws ClientProtocolException, IOException {
		HttpEntity httpEntity= com.csii.mobilebanking.tool.HttpUtils.executeHttpPost(URL,json);
		if (httpEntity!=null)
		{
			String srcstr=EntityUtils.toString(httpEntity,"UTF-8");
			
			try {
				srcstr=DES.decryptDES(srcstr, DES.decryptKey);
				srcstr=URLDecoder.decode(srcstr);
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			return srcstr;
		}
		else
			return "";
	}

	public static String cxm_SimpleTypeArray_JsonStr(Object[] objects)
	{
		//    	Log.e(csTAG, objects[0].getClass().getSimpleName());
		String mType = objects[0].getClass().getSimpleName();
		if (mType.equals("String"))
		{
			JSONArray jsArray  = new JSONArray();
			for (Object object : objects) {
				jsArray.put( object);
			}
			return jsArray.toString();
		}else
		{
			return "";
		}
	}













	// Value To Ro String
	public static String cxmGetRoJsonStr(String Value, String VarName){
		return "\"" + VarName + "\":\"" + FixJsonBug(Value).replaceAll("/u", "\\\\u") + "\"";  
	}

	public static String cxmGetRoJsonStr(boolean Value, String VarName){
		return "\"" + VarName + "\":\"" + Boolean.toString(Value) + "\"";  
	}

	public static String cxmGetRoJsonStr(int Value, String VarName){
		return "\"" + VarName + "\":\"" + Integer.toString(Value) + "\"";  
	}

	public static String cxmGetRoJsonStr(long Value, String VarName){
		return "\"" + VarName + "\":\"" + Long.toString(Value) + "\"";  
	}

	public static String cxmGetRoJsonStr(double Value, String VarName){
		return "\"" + VarName + "\":\"" + Double.toString(Value) + "\"";  
	}

	public static String cxmGetRoJsonStr(Time Value, String VarName){
		return "\"" + VarName + "\":\"" + ConvertTime(Value) + "\"";  
	}

	public static String cxmGetRoJsonStr(Object obj, String VarName) throws IllegalArgumentException, IllegalAccessException, JSONException{
		return "\"" + VarName + "\":"+ cxmGetRoJsonStr(obj).replaceAll("/u","\\u") ;
	}

	public static <T> String cxmGetRoJsonStr(List<T> objList, String VarName) throws IllegalArgumentException, IllegalAccessException, JSONException{
		return "\"" + VarName + "\":"+ cxmGetRoJsonStr(objList).replaceAll("/u", "\\u") ;
	}




































    //JosnObject To Value
	public static String cxmJoToString(JSONObject JO, String name) throws JSONException{
		return JO.getString(name);
	}
	
	protected static boolean cxmJoToboolean(JSONObject JO, String name) throws JSONException{
		return JO.getBoolean(name);
	}
	
	public static int cxmJoToint(JSONObject JO, String name) throws JSONException{
		return JO.getInt(name);
	}

	protected static long cxmJoTolong(JSONObject JO, String name) throws JSONException{
		return JO.getLong(name);
	}
	
	protected static double cxmJoTodouble(JSONObject JO, String name) throws JSONException{
		return Float.parseFloat(JO.getString(name));
	}

	public static Time cxmJoToTime(JSONObject JO, String name) throws JSONException{
		Time time = new Time();			
		String stemp = JO.getString(name);
		stemp=stemp.substring(0,19);	
		time.parse3339(stemp);	
		return time;
	}


	@SuppressWarnings({ "unchecked", "rawtypes" })
	public static <T> void cxmJoToList(List<T> objList, JSONArray JA, Class aClass) throws IllegalArgumentException, IllegalAccessException, JSONException, InstantiationException
	{
		int length = JA.length();
		for(int i = 0; i < length; i++){
			Object obj = aClass.newInstance();
			try {
				cxmJoToObject(obj, JA.getJSONObject(i));			
				objList.add((T) obj);
			} catch (Exception e) {
				e.printStackTrace();
//				objList.add(null);
			}
		}
	}

	public static void cxmJoToObject(Object obj, JSONObject JO) throws IllegalArgumentException, IllegalAccessException, JSONException
	{
		try{
		JSONObject sub_result;
		Field[] selfFields = obj.getClass().getDeclaredFields();
		Field[] superfields= obj.getClass().getSuperclass().getDeclaredFields();
		Field[] fullFields=new Field[selfFields.length+superfields.length];
		System.arraycopy(selfFields, 0, fullFields, 0, selfFields.length);
		System.arraycopy(superfields, 0, fullFields, selfFields.length, superfields.length);
		for(int i = 0; i < fullFields.length; i++)
		{
			Field afield = fullFields[i];
			afield.setAccessible(true);
			String fname = afield.getName();
			String tname = afield.getType().getName();
			Class<?> fieldtype=afield.getType(); 
			if (JO.has(fname)&& (!JO.isNull(fname)))
			{
				if (tname.indexOf(libperfix)>-1)
				{	
					if (!JO.isNull(fname))
					{
						sub_result = JO.getJSONObject(fname);					
						cxmJoToObject(afield.get(obj), sub_result);
					}
				}
				else if (fieldtype==int.class || fieldtype==Integer.class) 
				{
					afield.set(obj, JO.getInt(fname));
				} else if (fieldtype==long.class || fieldtype==Long.class) 
				{
					afield.set(obj, JO.getLong(fname));
				} else if (fieldtype==double.class || fieldtype==Double.class) 
				{
					afield.set(obj, JO.getDouble(fname));
				} else if (fieldtype==boolean.class|| fieldtype==Boolean.class) 
				{
					afield.set(obj, JO.getBoolean(fname));
				} else if (fieldtype==Time.class) 
				{
					Time time;
					if (afield.get(obj) == null) 
					{
						time = new Time();
						afield.set(obj, time);
					} else 
					{
						time = (Time) afield.get(obj);
					}
					String stemp = JO.getString(fname);
					stemp = stemp.substring(0, 19);
					time.parse3339(stemp);
				}else if(fname.equals("LottID")){
					afield.set(obj,String.valueOf(JO.get(fname)));
				}
				else 
				{					
					afield.set(obj,JO.get(fname));
				}
			}
		}	
		}catch (Exception e) {
			e.printStackTrace();
		}
	}
}